package service

import (
	"awesomeProject/app/model"
	"awesomeProject/app/request"
	"awesomeProject/app/response"
	"awesomeProject/global"
	"awesomeProject/util"
	"context"
	"github.com/shopspring/decimal"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"strconv"
	"strings"
	"time"
)

type ShopTrendSrv struct{}

func (s *ShopTrendSrv) ShopTrend(req request.ShopTrend) response.Resp {
	// 构造查询条件
	listFilter := bson.D{{"shop_id", strconv.Itoa(int(req.ShopId))}}
	sumFilter := bson.D{{"shop_id", strconv.Itoa(int(req.ShopId))}}
	preSumFilter := bson.D{{"shop_id", strconv.Itoa(int(req.ShopId))}}
	if req.DateVal != "" {
		if req.DateType == 1 || req.DateType == 4 { // 日期
			dateVal, _ := time.Parse("2006-01-02", req.DateVal)
			sDate := dateVal.AddDate(0, 0, -7)
			preSDate := dateVal.AddDate(0, 0, -1)
			listFilter = append(listFilter, bson.E{Key: "date", Value: bson.M{"$gte": sDate, "$lte": dateVal}})
			sumFilter = append(sumFilter, bson.E{Key: "date", Value: dateVal})
			preSumFilter = append(preSumFilter, bson.E{Key: "date", Value: preSDate})
		} else if req.DateType == 2 || req.DateType == 3 { // 近7天or近30天
			dateRange := strings.Split(req.DateVal, "~")
			subDays := -7
			if req.DateType == 3 {
				subDays = -30
			}
			sDate, _ := time.Parse("2006-01-02", dateRange[0])
			eDate, _ := time.Parse("2006-01-02", dateRange[1])
			preSDate := sDate.AddDate(0, 0, subDays)
			preEDate := eDate.AddDate(0, 0, subDays)
			listFilter = append(listFilter, bson.E{Key: "date", Value: bson.M{"$gte": sDate, "$lte": eDate}})
			sumFilter = append(sumFilter, bson.E{Key: "date", Value: bson.M{"$gte": sDate, "$lte": eDate}})
			preSumFilter = append(preSumFilter, bson.E{Key: "date", Value: bson.M{"$gte": preSDate, "$lte": preEDate}})
		} else if req.DateType == 5 { // 月份
			month, _ := time.Parse("2006-01", req.DateVal)
			preMonth := month.AddDate(0, -1, 0)
			sd := util.GetMonthStartAndEnd(month.Year(), int(month.Month()))
			preSd := util.GetMonthStartAndEnd(preMonth.Year(), int(preMonth.Month()))
			listFilter = append(listFilter, bson.E{Key: "date", Value: bson.M{"$gte": sd["start"], "$lte": sd["end"]}})
			sumFilter = append(sumFilter, bson.E{Key: "date", Value: bson.M{"$gte": sd["start"], "$lte": sd["end"]}})
			preSumFilter = append(preSumFilter, bson.E{Key: "date", Value: bson.M{"$gte": preSd["start"], "$lte": preSd["end"]}})
		}
	}

	match := bson.D{{"$match", listFilter}}
	project := bson.D{{
		"$project", bson.D{
			{"shop_id", bson.M{"$toInt": "$shop_id"}},
			{"date", 1},
			{"ctm_item_view_uv", bson.M{"$toInt": "$ctm_item_view_uv"}},
			{"order_buyer_cnt", bson.M{"$toInt": "$order_buyer_cnt"}},
			{"ctm_item_view_pv", bson.M{"$toInt": "$ctm_item_view_pv"}},
			{"ctm_item_view_item_cnt", bson.M{"$toInt": "$ctm_item_view_item_cnt"}},
			{"item_verified_cnt", bson.M{"$toInt": "$item_verified_cnt"}},
			{"item_verified_uv", bson.M{"$toInt": "$item_verified_uv"}},
			{"item_verified_usd", bson.M{"$toDouble": "$item_verified_usd"}},
			{"total_settle_amount", bson.M{"$toDouble": "$total_settle_amount"}},
			{"overtime_settle_amount", bson.M{"$toDouble": "$overtime_settle_amount"}},
			//{"overtime_rate", bson.M{"$toDouble": "$overtime_rate"}},
			//{"ctm_order_view_rate", bson.M{"$toDouble": "$ctm_order_view_rate"}},
			//{"per_customer_value", bson.M{"$toDouble": "$per_customer_value"}},
			//{"per_customer_value", bson.M{"$toDouble": "$per_customer_value"}},
		},
	}}
	sort := bson.D{{"$sort", bson.M{"date": -1}}}
	cursor, err := global.MongoDB.Collection("shop_trend").Aggregate(context.TODO(), mongo.Pipeline{match, project, sort})
	if err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}
	var trends []model.ShopTrend
	if err = cursor.All(context.TODO(), &trends); err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}

	group := bson.D{{
		"$group", bson.D{
			{"_id", nil},
			{"shop_id", bson.M{"$last": bson.M{"$toInt": "$shop_id"}}},
			{"item_verified_usd", bson.M{"$sum": bson.M{"$toDouble": "$item_verified_usd"}}},
			{"total_settle_amount", bson.M{"$sum": bson.M{"$toDouble": "$total_settle_amount"}}},
			{"overtime_settle_amount", bson.M{"$sum": bson.M{"$toDouble": "$overtime_settle_amount"}}},
			{"ctm_item_view_uv", bson.M{"$sum": bson.M{"$toInt": "$ctm_item_view_uv"}}},
			{"order_buyer_cnt", bson.M{"$sum": bson.M{"$toInt": "$order_buyer_cnt"}}},
			{"ctm_item_view_pv", bson.M{"$sum": bson.M{"$toInt": "$ctm_item_view_pv"}}},
			{"ctm_item_view_item_cnt", bson.M{"$sum": bson.M{"$toInt": "$ctm_item_view_item_cnt"}}},
			{"item_verified_cnt", bson.M{"$sum": bson.M{"$toInt": "$item_verified_cnt"}}},
			{"item_verified_uv", bson.M{"$sum": bson.M{"$toInt": "$item_verified_uv"}}},
		},
	}}
	sumMatch := bson.D{{
		"$match", sumFilter,
	}}
	sumCursor, err := global.MongoDB.Collection("shop_trend").Aggregate(context.TODO(), mongo.Pipeline{sumMatch, group})
	if err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}
	var sumTrends []model.ShopTrendCompare
	if err = sumCursor.All(context.TODO(), &sumTrends); err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}

	preSumMatch := bson.D{{
		"$match", preSumFilter,
	}}
	preSumCursor, err := global.MongoDB.Collection("shop_trend").Aggregate(context.TODO(), mongo.Pipeline{preSumMatch, group})
	if err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}
	var preSumTrends []model.ShopTrendCompare
	if err = preSumCursor.All(context.TODO(), &preSumTrends); err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}

	if len(sumTrends) == 0 {
		sumTrends = append(sumTrends, model.ShopTrendCompare{})
	}
	if len(preSumTrends) == 0 {
		preSumTrends = append(preSumTrends, model.ShopTrendCompare{})
	}

	// -----------------计算逻辑---------------------
	sumTrend, preSumTrend := sumTrends[0], preSumTrends[0]
	// 超时罚金比=0.1*超时商品结算价之和/订单结算价之和
	sumTrend.OvertimeRate = decimal.NewFromFloat(0.1).Mul(util.Div(
		sumTrend.OvertimeSettleAmount,
		sumTrend.TotalSettleAmount,
	))
	preSumTrend.OvertimeRate = decimal.NewFromFloat(0.1).Mul(util.Div(
		preSumTrend.OvertimeSettleAmount,
		preSumTrend.TotalSettleAmount,
	))
	//compareOvertimeRate := decimal.NewFromFloat(0)
	sumTrend.CompareOvertimeRate = util.IncreasePercent(preSumTrend.OvertimeRate, sumTrend.OvertimeRate)

	// 商品浏览量
	sumTrend.CompareCtmItemViewPv = util.IncreasePercent(preSumTrend.CtmItemViewPv, sumTrend.CtmItemViewPv)

	// 下单转化率
	sumTrend.CtmOrderViewRate = util.RatePercent(sumTrend.OrderBuyerCnt, sumTrend.CtmItemViewUv)
	preSumTrend.CtmOrderViewRate = util.RatePercent(preSumTrend.OrderBuyerCnt, preSumTrend.CtmItemViewUv)
	sumTrend.CompareCtmOrderViewRate = util.IncreasePercent(preSumTrend.CtmOrderViewRate, sumTrend.CtmOrderViewRate)

	// 客单价
	sumTrend.PerCustomerValue = util.Div(sumTrend.ItemVerifiedUsd, sumTrend.ItemVerifiedUv)
	preSumTrend.PerCustomerValue = util.Div(preSumTrend.ItemVerifiedUsd, preSumTrend.ItemVerifiedUv)
	sumTrend.ComparePerCustomerValue = util.IncreasePercent(preSumTrend.PerCustomerValue, sumTrend.PerCustomerValue)

	sumTrend.CompareItemVerifiedUsd = util.IncreasePercent(preSumTrend.ItemVerifiedUsd, sumTrend.ItemVerifiedUsd)

	sumTrend.CompareViewItemVerifiedRate = util.IncreasePercent(preSumTrend.ViewItemVerifiedRate, sumTrend.ViewItemVerifiedRate)

	sumTrend.CompareTotalSettleAmount = util.IncreasePercent(preSumTrend.TotalSettleAmount, sumTrend.TotalSettleAmount)

	sumTrend.CompareOvertimeSettleAmount = util.IncreasePercent(preSumTrend.OvertimeSettleAmount, sumTrend.OvertimeSettleAmount)

	sumTrend.CompareCtmItemViewUv = util.IncreasePercent(preSumTrend.CtmItemViewUv, sumTrend.CtmItemViewUv)

	sumTrend.CompareOrderBuyerCnt = util.IncreasePercent(preSumTrend.OrderBuyerCnt, sumTrend.OrderBuyerCnt)

	sumTrend.CompareCtmItemViewItemCnt = util.IncreasePercent(preSumTrend.CtmItemViewItemCnt, sumTrend.CtmItemViewItemCnt)

	sumTrend.CompareItemVerifiedCnt = util.IncreasePercent(preSumTrend.ItemVerifiedCnt, sumTrend.ItemVerifiedCnt)

	sumTrend.CompareItemVerifiedUv = util.IncreasePercent(preSumTrend.ItemVerifiedUv, sumTrend.ItemVerifiedUv)

	respData := map[string]interface{}{}
	respData["list"] = trends
	respData["total"] = sumTrend
	return response.OK.WithData(respData)
}
